<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.9.1"/>
<title>ht&#39;s Scheme Interpreter: README</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { init_search(); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">ht&#39;s Scheme Interpreter
   &#160;<span id="projectnumber">1.0</span>
   </div>
   <div id="projectbrief">a simplified scheme interpreter implementation</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.9.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('md__r_e_a_d_m_e.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">README </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>#htScheme A structured and plugin-based scheme interpreter implementation.</p>
<h2>How to use</h2>
<h3>Prerequisites</h3>
<ul>
<li>A modern C++ compiler supporting c++11 feature. (gcc4.9.2, gcc5.1, clang3.6 have been tested on Linux)</li>
<li>GNU Make (Make v4.0 has been tested on Linux)</li>
</ul>
<h3>Make</h3>
<p>Enter the <code>scheme</code> directory and run the following commands to generate various targets:</p>
<table class="doxtable">
<tr>
<th align="center"><b>Command</b> </th><th align="center"><b>Function</b>  </th></tr>
<tr>
<td align="center"><code>make</code>=<code>make all</code> </td><td align="center">Call everything below except <code>dep</code> and <code>clean</code> </td></tr>
<tr>
<td align="center"><code>make cli</code> </td><td align="center">Generate <code>cli</code> (the command-line interpreter frontend) </td></tr>
<tr>
<td align="center"><code>make dep</code> </td><td align="center">Generate <code><a class="el" href="dep_8d.html">dep.d</a></code> which contains the dependencies of files </td></tr>
<tr>
<td align="center"><code>make clean</code> </td><td align="center">Remove all files generated by <code>make</code> </td></tr>
<tr>
<td align="center"><code>make preprocessortest</code></td><td align="center">Generate <code>preprocessortest</code> </td></tr>
<tr>
<td align="center"><code>make tokenizertest</code> </td><td align="center">Generate <code>tokenizertest</code> </td></tr>
<tr>
<td align="center"><code>make asttest</code> </td><td align="center">Generate <code>asttest</code> </td></tr>
<tr>
<td align="center"><code>make parserstest</code> </td><td align="center">Generate <code>parserstest</code> </td></tr>
<tr>
<td align="center"><code>make biginttest</code> </td><td align="center">Generate <code>biginttest</code> </td></tr>
<tr>
<td align="center"><code>make rationaltypetest</code></td><td align="center">Generate <code>rationaltypetest</code> </td></tr>
</table>
<p>You may notice that the compilation is rather slow, therefore you can add <code>-j4</code> to <code>make</code> command in order to parallel the compilation with four threads.</p>
<h2>How to develop with htScheme</h2>
<p>htScheme has been designed as an extensible architecture of scheme-like languages, thus new types of tokens as well as parsers could be easily added into this program.</p>
<h3>Brief introduction to files</h3>
<h4><a class="el" href="preprocessor_8hpp.html">preprocessor.hpp</a>/cpp</h4>
<p>```cpp class <a class="el" href="class_scheme_unit.html">SchemeUnit</a> { public: <a class="el" href="class_scheme_unit.html">SchemeUnit(std::istream&amp; schemeStream)</a>; std::vector&lt;std::string&gt; lines; void preprocess(std::istream&amp; schemeStream); }; ``<code> Accept a</code>std::istream&lt;tt&gt;as the parameter, then read lines from it untilschemeStream.eof()<code>and remove the comments with the result stored in</code>lines`.</p>
<h4><a class="el" href="tokenizer_8hpp.html">tokenizer.hpp</a>/cpp</h4>
<p>```cpp class <a class="el" href="class_tokenizer.html">Tokenizer</a> { public: <a class="el" href="class_tokenizer.html">Tokenizer(const std::vector&lt;std::string&gt;&amp; lines)</a>; void split(const std::vector&lt;std::string&gt;&amp; lines); void parse(const std::list&lt;std::string&gt;&amp; rawTokens); std::list&lt;std::string&gt; rawTokens; std::list&lt;Token&gt; tokens; bool complete; }; ``<code> Accept lines of program, Then</code><a class="el" href="class_tokenizer.html#a2a6c04ea8c784f66bebcb6df7073769c">Tokenizer::Tokenizer&lt;tt&gt;</a>will call<a class="el" href="class_tokenizer.html">Tokenizer</a>:split<code>and</code>Tokernizer::parse` in order.</p>
<p><code><a class="el" href="class_tokenizer.html#a8bd8a4eb5df764f6128028daa0e9044b">Tokenizer::split</a></code> splits <code>lines</code> into several small string pieces stored in <code><a class="el" href="class_tokenizer.html#a89707ad3a758fc9ec58f00d92d5fc622">Tokenizer::rawTokens</a></code>. For example, <code>(string-ith "123 34" 2)</code> will be split into ``` ( string-ith "123 34" 2 ) ```</p>
<p><code><a class="el" href="class_tokenizer.html#ae928efe72c00908a3529747b4cfd01d5">Tokenizer::parse</a></code> convert <code><a class="el" href="class_tokenizer.html#a89707ad3a758fc9ec58f00d92d5fc622">Tokenizer::rawTokens</a></code> to <code><a class="el" href="class_tokenizer.html#ae547093dbd03b3e70373147e4669d9fa">Tokenizer::tokens</a></code>.</p>
<p><code><a class="el" href="struct_token.html">Token</a></code> is defined as followed in <code><a class="el" href="types_2all_8hpp.html">types/all.hpp</a></code>: ```cpp struct <a class="el" href="struct_token.html">Token</a> { TokenType tokenType; //enum TokenType {OpPlus, ...} InfoTypes info; //typedef boost::variant&lt;InfoType1, ...&gt; InfoTypes }; ```</p>
<p>There is an extra variable <code><a class="el" href="class_tokenizer.html#a330a4cce0cbf3ebfbe601d97022d1ed4">Tokenizer::complete</a></code> in this class, which represents whether there is no incomplete brackets or quotaion marks. This could be useful in building command-line interpreter. <code><a class="el" href="class_tokenizer.html#a330a4cce0cbf3ebfbe601d97022d1ed4">Tokenizer::complete</a></code> can be set by both <code><a class="el" href="class_tokenizer.html#a8bd8a4eb5df764f6128028daa0e9044b">Tokenizer::split</a></code> and <code><a class="el" href="class_tokenizer.html#ae928efe72c00908a3529747b4cfd01d5">Tokenizer::parse</a></code>.</p>
<h4><a class="el" href="ast_8hpp.html">ast.hpp</a>/cpp</h4>
<p>```cpp class <a class="el" href="class_a_s_t.html">AST</a> { public: <a class="el" href="struct_a_s_t_node.html">ASTNode</a> astHead; void buildAST(const std::list&lt;Token&gt; &amp;tokens); <a class="el" href="class_a_s_t.html">AST</a> (const std::list&lt;Token&gt; &amp;tokens); <a class="el" href="class_a_s_t.html">AST()</a>; friend std::ostream&amp; operator &lt;&lt; (std::ostream&amp; o, const <a class="el" href="class_a_s_t.html">AST</a>&amp; ast); }; ``<code> Build an <a class="el" href="class_a_s_t.html">AST</a> which could be accessed through</code><a class="el" href="class_a_s_t.html#a4f9b6d3be381682515e1e51c176b1c21">AST.astHead&lt;tt&gt;</a>withstd::list&lt;Token&gt;`.</p>
<p>Here is the definition of <code><a class="el" href="struct_a_s_t_node.html">ASTNode</a></code>: ```cpp struct <a class="el" href="struct_a_s_t_node.html">ASTNode</a> { NodeType type; //enum NodeType {Bracket, Simple}; <a class="el" href="struct_token.html">Token</a> token; ASTNode* parent; std::list&lt;ASTNode*&gt; ch;</p>
<p>ASTNode* add(const ASTNode&amp; node); //ch.push_back(new ASTNode(node)) void remove(); //Recursively remove all its children then clear ch }; ```</p>
<p>For example, <code>(+ 2.7 (- 5.6 2.1) 3)</code> will be converted to the following <a class="el" href="class_a_s_t.html">AST</a>: ``` Type:0 <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:0 //astHead +-&mdash;Type:Bracket <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:0 +&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:OpPlus |&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:2.7 TokenType:Float |&mdash;Type:Bracket <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:0 | +&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:OpMinus | |&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:5.6 TokenType:Float | |&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:2.1 TokenType:Float |&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:3 TokenType:Float ```</p>
<h4><a class="el" href="parsers_8hpp.html">parsers.hpp</a></h4>
<p>The main part of <code><a class="el" href="parsers_8hpp.html">parsers.hpp</a></code> is in <code><a class="el" href="parsers_2all_8hpp.html">parsers/all.hpp</a></code></p>
<p>```cpp class <a class="el" href="class_parsers_helper.html">ParsersHelper</a> { <a class="el" href="class_parsers_helper.html">ParsersHelper()</a>; void parse(ASTNode&amp; astnode); }; ``<code> Provide a reference of</code><a class="el" href="struct_a_s_t_node.html">ASTNode</a><code>to an instance of</code><a class="el" href="class_parsers_helper.html#a21ce6213ee29e0459dd655c6803db00b">ParsersHelper::parse&lt;tt&gt;</a>, then<a class="el" href="class_parsers_helper.html">ParsersHelper</a><code>will call according</code>xxxASTParser::parse(ASTNode&amp; parent, ParsersHelper&amp; helper)<code>to recursively calculate the result of a subtree of <a class="el" href="class_a_s_t.html">AST</a> with its root as</code>astnode<code>. After</code><a class="el" href="class_parsers_helper.html#a21ce6213ee29e0459dd655c6803db00b">ParsersHelper::parse&lt;tt&gt;</a>,astnode.type&lt;tt&gt;will becomeSimple<code>. If</code>astnode<code>is already a</code>Simple` node, nothing will be done.</p>
<p>The parsed version of the above <a class="el" href="class_a_s_t.html">AST</a> is (by calling <code>parse( **ast.headNode.ch.begin() )</code>: ``` Type:1 <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:0 TokenType:0 //headNode +-&mdash;Type:Simple <a class="el" href="struct_token.html#a4c338f6ca199f4a8575e877d36d03a06">Token.info</a>:9.2 TokenType:Float ```</p>
<p><b>Warning</b> &ndash;DO NOT&ndash; directly call <code>helper.parse(*ch[xx])</code> in <code>xxxASTParser::parse(ASTNode&amp; parent, ParsersHelper&amp; helper)</code> ! Instead, you should copy construct a new <code><a class="el" href="class_parsers_helper.html">ParsersHelper</a></code> to parse its children.</p>
<h3>Add your own <a class="el" href="struct_token.html">Token</a> Parser</h3>
<p>In this section, we will try to add a new <code>Rational</code> type of token.</p>
<h4>Step1: Register the Rational Type</h4>
<p>Open <code><a class="el" href="types_2arch_8hpp.html">types/arch.hpp</a></code>, add <code>Rational</code> to <code>enum TokenType{ ... , Rational }</code></p>
<h4>Step2: Register the Rational Parser</h4>
<ul>
<li>Open <code><a class="el" href="types_2all_8hpp.html">types/all.hpp</a></code>, add <code>RationalParser</code> to <code>#define PARSERS_TUPLE (..., RationalParser)</code></li>
<li><code>#include "rational.hpp"</code></li>
</ul>
<h4>Step3: Write the Header</h4>
<ul>
<li>Create <code><a class="el" href="rational_8hpp.html">types/rational.hpp</a></code>, then include your declaration of your <code><a class="el" href="class_rational_type.html">RationalType</a></code> and <code>"arch.hpp"</code></li>
<li>Use the macro in <code>arch.hpp</code> to generate the declaration of your <code>RationalParser</code> : ``` <a class="el" href="types_2arch_8hpp.html#a669f5b829a7373f20602e4c063e01d99">PARSER_DECLARATION(RationalParser, Rational, RationalType)</a> ```</li>
</ul>
<h4>Step4: Implement the Parser</h4>
<ul>
<li>Create <code><a class="el" href="rational_8cpp.html">types/rational.cpp</a></code>, then <code>#include "rational.hpp"</code> and implement your <code><a class="el" href="class_rational_type.html">RationalType</a></code> in it.</li>
<li>Implement <code>bool RationalParser::judge(const std::string&amp; token)</code> which returns whether a token is a rational token and <code>RationalParser::InfoType RationalParser::get(const std::string&amp; token)</code> which converts the token to <code>RationalParser::InfoType</code>(aka <code><a class="el" href="class_rational_type.html">RationalType</a></code>)</li>
<li><code>const TokenType RationalParser::type = Rational;</code> </li>
</ul>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
  </ul>
</div>
</body>
</html>
